<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
	<head>
		<title>Works</title>
<link href="../docs-assets/Breadcrumbs.css" rel="stylesheet" rev="stylesheet" type="text/css">
		<meta name="viewport" content="width=device-width initial-scale=1">
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
		<meta http-equiv="Content-Language" content="en-gb">

<link href="../docs-assets/Contents.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Progress.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Navigation.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Fonts.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Base.css" rel="stylesheet" rev="stylesheet" type="text/css">
<script>
function togglePopup(material_id) {
  var popup = document.getElementById(material_id);
  popup.classList.toggle("show");
}
</script>

<link href="../docs-assets/Popups.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Colours.css" rel="stylesheet" rev="stylesheet" type="text/css">
		
	</head>
	<body class="commentary-font">
		<nav role="navigation">
		<h1><a href="../index.html"><img src="../docs-assets/Inform.png" height=72> </a></h1>
<ul><li><a href="../index.html">home</a></li>
</ul><h2>Compiler</h2><ul>
<li><a href="../structure.html">structure</a></li>
<li><a href="../inbuildn.html">inbuild</a></li>
<li><a href="../inform7n.html">inform7</a></li>
<li><a href="../intern.html">inter</a></li>
<li><a href="../services.html">services</a></li>
<li><a href="../secrets.html">secrets</a></li>
</ul><h2>Other Tools</h2><ul>
<li><a href="../inblorbn.html">inblorb</a></li>
<li><a href="../inform6.html">inform6</a></li>
<li><a href="../inpolicyn.html">inpolicy</a></li>
</ul><h2>Resources</h2><ul>
<li><a href="../extensions.html">extensions</a></li>
<li><a href="../kits.html">kits</a></li>
</ul><h2>Repository</h2><ul>
<li><a href="https://github.com/ganelson/inform"><img src="../docs-assets/github.png" height=0> github</a></li>
</ul><h2>Related Projects</h2><ul>
<li><a href="https://github.com/ganelson/inweb"><img src="../docs-assets/github.png" height=0> inweb</a></li>
<li><a href="https://github.com/ganelson/intest"><img src="../docs-assets/github.png" height=0> intest</a></li>
</ul>
		</nav>
		<main role="main">
		<!-- Weave of 'Works' generated by inweb -->
<div class="breadcrumbs">
    <ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../inbuildn.html">Inbuild Modules</a></li><li><a href="index.html">supervisor</a></li><li><a href="index.html#2">Chapter 2: Conceptual Framework</a></li><li><b>Works</b></li></ul></div>
<p class="purpose">To store, hash code and compare title/author pairs used to identify works.</p>

<ul class="toc"><li><a href="2-wrk.html#SP1">&#167;1. Works</a></li><li><a href="2-wrk.html#SP6">&#167;6. Printing</a></li><li><a href="2-wrk.html#SP9">&#167;9. Identification</a></li><li><a href="2-wrk.html#SP12">&#167;12. Documentation links</a></li></ul><hr class="tocbar">

<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>&#167;1. Works.</b>A "work" is a single artistic or programming creation; for example, the IF
story Bronze by Emily Short might be a work. Many versions of this IF story
may exist over time, but they will all be versions of the same "work".
Extensions are also works: for example, Epistemology by Eric Eve is a work.
</p>

<p class="commentary">Works are identified by the pair of title and author name, each of which is an
ISO Latin-1 string limited in length, with certain bad-news characters
excluded (such as <span class="extract"><span class="extract-syntax">/</span></span> and <span class="extract"><span class="extract-syntax">:</span></span>) so that they can be used directly in filenames.
However, we will not want to compare these by string comparison: so we
hash-code the combination for speed. The following structure holds a
combination of the textual names and the hash code:
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">inbuild_work</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">inbuild_genre</span><span class="plain-syntax"> *</span><span class="identifier-syntax">genre</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">author_name</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">raw_author_name</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">title</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">raw_title</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">inbuild_work_hash_code</span><span class="plain-syntax">; </span><span class="comment-syntax"> hash code derived from the above</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">CLASS_DEFINITION</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">inbuild_work</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>The structure inbuild_work is accessed in 2/edt, 2/cps, 2/ce, 2/rqr, 2/jm, 3/bg, 3/is, 3/is2, 4/em, 4/ebm, 4/km, 4/lm, 4/pm, 4/pbm, 4/pfm, 4/tm, 5/es, 5/ks, 5/ls, 5/ps2, 6/inc, 7/tm, 7/eip, 7/ti, 7/tc, 7/dc, 7/dr, 7/im, 7/mrp and here.</li></ul>
<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>&#167;2. </b>Each work structure is written only once, and its title and author name are
not subsequently altered.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">inbuild_work</span><span class="plain-syntax"> *</span><span class="function-syntax">Works::new</span><button class="popup" onclick="togglePopup('usagePopup1')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup1">Usage of <span class="code-font"><span class="function-syntax">Works::new</span></span>:<br/><a href="2-wrk.html#SP11">&#167;11</a><br/>Requirements - <a href="2-rqr.html#SP2">&#167;2</a><br/>Inter Skill - <a href="3-is.html#SP3">&#167;3</a>, <a href="3-is.html#SP4">&#167;4</a><br/>Extension Manager - <a href="4-em.html#SP4">&#167;4</a><br/>Language Manager - <a href="4-lm.html#SP3">&#167;3</a><br/>Project Bundle Manager - <a href="4-pbm.html#SP2">&#167;2</a><br/>Project File Manager - <a href="4-pfm.html#SP2">&#167;2</a><br/>Template Manager - <a href="4-tm.html#SP3">&#167;3</a><br/>Extension Services - <a href="5-es.html#SP2_4_3_1">&#167;2.4.3.1</a>, <a href="5-es.html#SP2_4_3_2">&#167;2.4.3.2</a>, <a href="5-es.html#SP2_6">&#167;2.6</a>, <a href="5-es.html#SP23">&#167;23</a><br/>Kit Services - <a href="5-ks.html#SP5_3_1">&#167;5.3.1</a>, <a href="5-ks.html#SP8">&#167;8</a><br/>Language Services - <a href="5-ls.html#SP11">&#167;11</a><br/>Project Services - <a href="5-ps2.html#SP18">&#167;18</a><br/>Headings - <a href="6-hdn.html#SP12_3">&#167;12.3</a><br/>Inclusions - <a href="6-inc.html#SP5_1">&#167;5.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inbuild_genre</span><span class="plain-syntax"> *</span><span class="identifier-syntax">genre</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ti</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">an</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="2-wrk.html#SP3" class="function-link"><span class="function-syntax">Works::new_inner</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">genre</span><span class="plain-syntax">, </span><span class="identifier-syntax">ti</span><span class="plain-syntax">, </span><span class="identifier-syntax">an</span><span class="plain-syntax">, </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">inbuild_work</span><span class="plain-syntax"> *</span><span class="function-syntax">Works::new_raw</span><button class="popup" onclick="togglePopup('usagePopup2')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup2">Usage of <span class="code-font"><span class="function-syntax">Works::new_raw</span></span>:<br/>Extension Bundle Manager - <a href="4-ebm.html#SP3">&#167;3</a><br/>Kit Manager - <a href="4-km.html#SP3">&#167;3</a><br/>Pipeline Manager - <a href="4-pm.html#SP4">&#167;4</a><br/>Extension Services - <a href="5-es.html#SP2_3">&#167;2.3</a><br/>Project Services - <a href="5-ps2.html#SP21">&#167;21</a>, <a href="5-ps2.html#SP23_1">&#167;23.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inbuild_genre</span><span class="plain-syntax"> *</span><span class="identifier-syntax">genre</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ti</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">an</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="2-wrk.html#SP3" class="function-link"><span class="function-syntax">Works::new_inner</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">genre</span><span class="plain-syntax">, </span><span class="identifier-syntax">ti</span><span class="plain-syntax">, </span><span class="identifier-syntax">an</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP3" class="paragraph-anchor"></a><b>&#167;3. </b>Though it is probably the case that the author name and title supplied are
already of normalised casing, we do not want to rely on that. Works intending
to represent (e.g.) the same extension but named with different casing
conventions would fail to match: and this could happen if a new build of
Inform were published which made a subtle change to the casing conventions,
but which continued to use an extension dictionary file first written by
previous builds under the previous conventions.
</p>

<p class="commentary">The "raw", i.e., not case-normalised, forms of the title and author name are
preserved for use in text output, but not identification.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">inbuild_work</span><span class="plain-syntax"> *</span><span class="function-syntax">Works::new_inner</span><button class="popup" onclick="togglePopup('usagePopup3')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup3">Usage of <span class="code-font"><span class="function-syntax">Works::new_inner</span></span>:<br/><a href="2-wrk.html#SP2">&#167;2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inbuild_genre</span><span class="plain-syntax"> *</span><span class="identifier-syntax">genre</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ti</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">an</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">norm</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">inbuild_work</span><span class="plain-syntax"> *</span><span class="identifier-syntax">work</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CREATE</span><span class="plain-syntax">(</span><span class="reserved-syntax">inbuild_work</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">work</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">genre</span><span class="plain-syntax"> = </span><span class="identifier-syntax">genre</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">work</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">raw_author_name</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Str::duplicate</span><span class="plain-syntax">(</span><span class="identifier-syntax">an</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">work</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">author_name</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Str::duplicate</span><span class="plain-syntax">(</span><span class="identifier-syntax">an</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">work</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">raw_title</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Str::duplicate</span><span class="plain-syntax">(</span><span class="identifier-syntax">ti</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">work</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">title</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Str::duplicate</span><span class="plain-syntax">(</span><span class="identifier-syntax">ti</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">norm</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><a href="2-wrk.html#SP4" class="function-link"><span class="function-syntax">Works::normalise_casing</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">work</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">author_name</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><a href="2-wrk.html#SP4" class="function-link"><span class="function-syntax">Works::normalise_casing</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">work</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">title</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="2-wrk.html#SP3_1" class="named-paragraph-link"><span class="named-paragraph">Compute the hash code</span><span class="named-paragraph-number">3.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">work</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP3_1" class="paragraph-anchor"></a><b>&#167;3.1. </b>We hash-code all works on arrival, using the X 30011 algorithm, on the text
of the pseudo-pathname <span class="extract"><span class="extract-syntax">Author/Title</span></span>. The result is an integer between 0 and
the following constant minus 1.
</p>

<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">WORK_HASH_CODING_BASE</span><span class="plain-syntax"> </span><span class="constant-syntax">499</span><span class="plain-syntax"> </span><span class="comment-syntax"> this is coprime to 30011</span>
</pre>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compute the hash code</span><span class="named-paragraph-number">3.1</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">hc</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOOP_THROUGH_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">, </span><span class="identifier-syntax">work</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">author_name</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">hc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">hc</span><span class="plain-syntax">*30011 + (</span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax">) </span><span class="identifier-syntax">Characters::tolower</span><span class="plain-syntax">(</span><span class="identifier-syntax">Str::get</span><span class="plain-syntax">(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">));</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">hc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">hc</span><span class="plain-syntax">*30011 + (</span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax">) </span><span class="character-syntax">'/'</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOOP_THROUGH_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">, </span><span class="identifier-syntax">work</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">title</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">hc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">hc</span><span class="plain-syntax">*30011 + (</span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax">) </span><span class="identifier-syntax">Characters::tolower</span><span class="plain-syntax">(</span><span class="identifier-syntax">Str::get</span><span class="plain-syntax">(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">));</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">hc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">hc</span><span class="plain-syntax"> % </span><span class="constant-syntax">WORK_HASH_CODING_BASE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">work</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">inbuild_work_hash_code</span><span class="plain-syntax"> = (</span><span class="reserved-syntax">int</span><span class="plain-syntax">) </span><span class="identifier-syntax">hc</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-wrk.html#SP3">&#167;3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP4" class="paragraph-anchor"></a><b>&#167;4. </b>Casing is normalised as follows. Every word is capitalised, where a word
begins at the start of the text, after a hyphen, or after a bracket. Thus
"Every Word Counts", "Even Double-Barrelled Ones (And Even Parenthetically)".
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Works::normalise_casing</span><button class="popup" onclick="togglePopup('usagePopup4')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup4">Usage of <span class="code-font"><span class="function-syntax">Works::normalise_casing</span></span>:<br/><a href="2-wrk.html#SP3">&#167;3</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">boundary</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOOP_THROUGH_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">, </span><span class="identifier-syntax">p</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">inchar32_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">c</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Str::get</span><span class="plain-syntax">(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">boundary</span><span class="plain-syntax">) </span><span class="identifier-syntax">Str::put</span><span class="plain-syntax">(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">, </span><span class="identifier-syntax">Characters::toupper</span><span class="plain-syntax">(</span><span class="identifier-syntax">c</span><span class="plain-syntax">));</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">Str::put</span><span class="plain-syntax">(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">, </span><span class="identifier-syntax">Characters::tolower</span><span class="plain-syntax">(</span><span class="identifier-syntax">c</span><span class="plain-syntax">));</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">boundary</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="character-syntax">' '</span><span class="plain-syntax">) </span><span class="identifier-syntax">boundary</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="character-syntax">'-'</span><span class="plain-syntax">) </span><span class="identifier-syntax">boundary</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="character-syntax">'('</span><span class="plain-syntax">) </span><span class="identifier-syntax">boundary</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP5" class="paragraph-anchor"></a><b>&#167;5. </b>This variant is more forgiving, in that it allows mixed-casing inside a
word, that is, after the opening letter. So "PDQ Bach" and "Marc DuQuesne"
would both pass, whereas <a href="2-wrk.html#SP4" class="internal">Works::normalise_casing</a> would make them into
"Pdq Bach" and "Marc Duquesne".
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Works::normalise_casing_mixed</span><button class="popup" onclick="togglePopup('usagePopup5')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup5">Usage of <span class="code-font"><span class="function-syntax">Works::normalise_casing_mixed</span></span>:<br/>Extension Services - <a href="5-es.html#SP2_2_1_1">&#167;2.2.1.1</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">boundary</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOOP_THROUGH_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">, </span><span class="identifier-syntax">p</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">inchar32_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">c</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Str::get</span><span class="plain-syntax">(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">boundary</span><span class="plain-syntax">) </span><span class="identifier-syntax">Str::put</span><span class="plain-syntax">(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">, </span><span class="identifier-syntax">Characters::toupper</span><span class="plain-syntax">(</span><span class="identifier-syntax">c</span><span class="plain-syntax">));</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">boundary</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="character-syntax">' '</span><span class="plain-syntax">) </span><span class="identifier-syntax">boundary</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="character-syntax">'-'</span><span class="plain-syntax">) </span><span class="identifier-syntax">boundary</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="character-syntax">'('</span><span class="plain-syntax">) </span><span class="identifier-syntax">boundary</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP6" class="paragraph-anchor"></a><b>&#167;6. Printing.</b>As noted above, the raw forms are used for output.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Works::write</span><button class="popup" onclick="togglePopup('usagePopup6')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup6">Usage of <span class="code-font"><span class="function-syntax">Works::write</span></span>:<br/>Editions - <a href="2-edt.html#SP1">&#167;1</a><br/>Build Graphs - <a href="3-bg.html#SP8">&#167;8</a>, <a href="3-bg.html#SP9">&#167;9</a><br/>The Installer - <a href="7-ti.html#SP2_2">&#167;2.2</a>, <a href="7-ti.html#SP3_1">&#167;3.1</a>, <a href="7-ti.html#SP5">&#167;5</a>, <a href="7-ti.html#SP9_1">&#167;9.1</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">OUTPUT_STREAM</span><span class="plain-syntax">, </span><span class="reserved-syntax">inbuild_work</span><span class="plain-syntax"> *</span><span class="identifier-syntax">work</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">VOID_METHOD_CALL</span><span class="plain-syntax">(</span><span class="identifier-syntax">work</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">genre</span><span class="plain-syntax">, </span><span class="constant-syntax">GENRE_WRITE_WORK_MTID</span><span class="plain-syntax">, </span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">work</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>

<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Works::write_to_HTML_file</span><button class="popup" onclick="togglePopup('usagePopup7')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup7">Usage of <span class="code-font"><span class="function-syntax">Works::write_to_HTML_file</span></span>:<br/><a href="2-wrk.html#SP7">&#167;7</a><br/>The Mini-Website - <a href="7-tm.html#SP9">&#167;9</a><br/>Documentation Renderer - <a href="7-dr.html#SP9">&#167;9</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">OUTPUT_STREAM</span><span class="plain-syntax">, </span><span class="reserved-syntax">inbuild_work</span><span class="plain-syntax"> *</span><span class="identifier-syntax">work</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">fancy</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"%S"</span><span class="plain-syntax">, </span><span class="identifier-syntax">work</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">raw_title</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">fancy</span><span class="plain-syntax">) </span><span class="identifier-syntax">HTML::begin_span</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"extensionindexentry"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" by "</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">fancy</span><span class="plain-syntax">) </span><span class="identifier-syntax">HTML::end_span</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"%S"</span><span class="plain-syntax">, </span><span class="identifier-syntax">work</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">raw_author_name</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP7" class="paragraph-anchor"></a><b>&#167;7. </b>The following is only sensible for extensions, and is used when Inform
generates its Extensions index entries.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Works::write_link_to_HTML_file</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUTPUT_STREAM</span><span class="plain-syntax">, </span><span class="reserved-syntax">inbuild_work</span><span class="plain-syntax"> *</span><span class="identifier-syntax">work</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">HTML_OPEN_WITH</span><span class="plain-syntax">(</span><span class="string-syntax">"a"</span><span class="plain-syntax">, </span><span class="string-syntax">"href='Extensions/%S/%S.html' style=\"text-decoration: none\""</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">work</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">author_name</span><span class="plain-syntax">, </span><span class="identifier-syntax">work</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">title</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">HTML::begin_span</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"extensionindexentry"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-wrk.html#SP11" class="function-link"><span class="function-syntax">Works::is_standard_rules</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">work</span><span class="plain-syntax">)) </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"%S"</span><span class="plain-syntax">, </span><span class="identifier-syntax">work</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">title</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><a href="2-wrk.html#SP6" class="function-link"><span class="function-syntax">Works::write_to_HTML_file</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">work</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">HTML::end_span</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">HTML_CLOSE</span><span class="plain-syntax">(</span><span class="string-syntax">"a"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP8" class="paragraph-anchor"></a><b>&#167;8. </b>The Inbuild module provides the <span class="extract"><span class="extract-syntax">%X</span></span> escape sequence for printing names of
works. (The X used to stand for Extension.) <span class="extract"><span class="extract-syntax">%&lt;X</span></span> provides an abbreviated form.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Works::writer</span><button class="popup" onclick="togglePopup('usagePopup8')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup8">Usage of <span class="code-font"><span class="function-syntax">Works::writer</span></span>:<br/>Supervisor Module - <a href="1-sm.html#SP3">&#167;3</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">OUTPUT_STREAM</span><span class="plain-syntax">, </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">format_string</span><span class="plain-syntax">, </span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">vE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">inbuild_work</span><span class="plain-syntax"> *</span><span class="identifier-syntax">work</span><span class="plain-syntax"> = (</span><span class="reserved-syntax">inbuild_work</span><span class="plain-syntax"> *) </span><span class="identifier-syntax">vE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">switch</span><span class="plain-syntax"> (</span><span class="identifier-syntax">format_string</span><span class="plain-syntax">[0]) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="character-syntax">'&lt;'</span><span class="plain-syntax">:</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">work</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"source text"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"%S"</span><span class="plain-syntax">, </span><span class="identifier-syntax">work</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">raw_title</span><span class="plain-syntax">);</span>
<span class="plain-syntax">                </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><a href="2-wrk.html#SP11" class="function-link"><span class="function-syntax">Works::is_standard_rules</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">work</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax">                    (</span><a href="2-wrk.html#SP11" class="function-link"><span class="function-syntax">Works::is_basic_inform</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">work</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">))</span>
<span class="plain-syntax">                    </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" by %S"</span><span class="plain-syntax">, </span><span class="identifier-syntax">work</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">raw_author_name</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            }</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="character-syntax">'X'</span><span class="plain-syntax">:</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">work</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"&lt;no extension&gt;"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"%S by %S"</span><span class="plain-syntax">, </span><span class="identifier-syntax">work</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">raw_title</span><span class="plain-syntax">, </span><span class="identifier-syntax">work</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">raw_author_name</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">default:</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"bad %X extension"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP9" class="paragraph-anchor"></a><b>&#167;9. Identification.</b>Two works with different hash codes definitely identify different works;
if the code is the same, we must use <span class="extract"><span class="extract-syntax">Str::eq</span></span> on the actual title and author
name.
</p>

<p class="commentary">(Note that this is not a lexicographic function suitable for sorting
works into alphabetical order: it cannot be, since the hash code is not
order-preserving. To emphasise this we return true or false rather than a
<span class="extract"><span class="extract-syntax">strcmp</span></span>-style delta value.)
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Works::match</span><button class="popup" onclick="togglePopup('usagePopup9')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup9">Usage of <span class="code-font"><span class="function-syntax">Works::match</span></span>:<br/><a href="2-wrk.html#SP11">&#167;11</a><br/>Headings - <a href="6-hdn.html#SP22">&#167;22</a>, <a href="6-hdn.html#SP22_2">&#167;22.2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inbuild_work</span><span class="plain-syntax"> *</span><span class="identifier-syntax">w1</span><span class="plain-syntax">, </span><span class="reserved-syntax">inbuild_work</span><span class="plain-syntax"> *</span><span class="identifier-syntax">w2</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">w1</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">w2</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"bad work match"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">w1</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">inbuild_work_hash_code</span><span class="plain-syntax"> != </span><span class="identifier-syntax">w2</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">inbuild_work_hash_code</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::eq_insensitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">w1</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">author_name</span><span class="plain-syntax">, </span><span class="identifier-syntax">w2</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">author_name</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::eq_insensitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">w1</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">title</span><span class="plain-syntax">, </span><span class="identifier-syntax">w2</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">title</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP10" class="paragraph-anchor"></a><b>&#167;10. </b>This is quite a deal slower, but is trichotomous and can be used for sorting.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Works::cmp</span><button class="popup" onclick="togglePopup('usagePopup10')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup10">Usage of <span class="code-font"><span class="function-syntax">Works::cmp</span></span>:<br/>Editions - <a href="2-edt.html#SP4">&#167;4</a><br/>Extension Services - <a href="5-es.html#SP7">&#167;7</a><br/>The Installer - <a href="7-ti.html#SP2_4_5">&#167;2.4.5</a>, <a href="7-ti.html#SP2_5_3">&#167;2.5.3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inbuild_work</span><span class="plain-syntax"> *</span><span class="identifier-syntax">w1</span><span class="plain-syntax">, </span><span class="reserved-syntax">inbuild_work</span><span class="plain-syntax"> *</span><span class="identifier-syntax">w2</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">w1</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">w2</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"bad work match"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">d</span><span class="plain-syntax"> = </span><a href="2-gnr.html#SP5" class="function-link"><span class="function-syntax">Genres::cmp</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">w1</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">genre</span><span class="plain-syntax">, </span><span class="identifier-syntax">w2</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">genre</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">d</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">d</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Str::cmp_insensitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">w1</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">author_name</span><span class="plain-syntax">, </span><span class="identifier-syntax">w2</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">author_name</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">d</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">d</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Str::cmp_insensitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">w1</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">title</span><span class="plain-syntax">, </span><span class="identifier-syntax">w2</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">title</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">d</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP11" class="paragraph-anchor"></a><b>&#167;11. </b>Because Basic Inform and the Standard Rules extensions are treated slightly
differently by the documentation, and so forth, it's convenient to provide a
single function testing if a work refers to them.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">inbuild_work</span><span class="plain-syntax"> *</span><span class="identifier-syntax">a_work_for_standard_rules</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Works::is_standard_rules</span><button class="popup" onclick="togglePopup('usagePopup11')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup11">Usage of <span class="code-font"><span class="function-syntax">Works::is_standard_rules</span></span>:<br/><a href="2-wrk.html#SP7">&#167;7</a>, <a href="2-wrk.html#SP8">&#167;8</a><br/>Extension Services - <a href="5-es.html#SP2">&#167;2</a><br/>Source Text - <a href="6-st.html#SP4">&#167;4</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inbuild_work</span><span class="plain-syntax"> *</span><span class="identifier-syntax">work</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">a_work_for_standard_rules</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">a_work_for_standard_rules</span><span class="plain-syntax"> =</span>
<span class="plain-syntax">            </span><a href="2-wrk.html#SP2" class="function-link"><span class="function-syntax">Works::new</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">extension_genre</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"Standard Rules"</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"Graham Nelson"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">work</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="2-wrk.html#SP9" class="function-link"><span class="function-syntax">Works::match</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">work</span><span class="plain-syntax">, </span><span class="identifier-syntax">a_work_for_standard_rules</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>

<span class="reserved-syntax">inbuild_work</span><span class="plain-syntax"> *</span><span class="identifier-syntax">a_work_for_basic_inform</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Works::is_basic_inform</span><button class="popup" onclick="togglePopup('usagePopup12')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup12">Usage of <span class="code-font"><span class="function-syntax">Works::is_basic_inform</span></span>:<br/><a href="2-wrk.html#SP8">&#167;8</a><br/>Extension Services - <a href="5-es.html#SP2">&#167;2</a><br/>Source Text - <a href="6-st.html#SP4">&#167;4</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inbuild_work</span><span class="plain-syntax"> *</span><span class="identifier-syntax">work</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">a_work_for_basic_inform</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">a_work_for_basic_inform</span><span class="plain-syntax"> =</span>
<span class="plain-syntax">            </span><a href="2-wrk.html#SP2" class="function-link"><span class="function-syntax">Works::new</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">extension_genre</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"Basic Inform"</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"Graham Nelson"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">work</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="2-wrk.html#SP9" class="function-link"><span class="function-syntax">Works::match</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">work</span><span class="plain-syntax">, </span><span class="identifier-syntax">a_work_for_basic_inform</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP12" class="paragraph-anchor"></a><b>&#167;12. Documentation links.</b>This is where HTML links to extension documentation are created; the URL for
each extension's page is generated from its <span class="extract"><span class="extract-syntax">inbuild_work</span></span>.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Works::begin_extension_link</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUTPUT_STREAM</span><span class="plain-syntax">, </span><span class="reserved-syntax">inbuild_work</span><span class="plain-syntax"> *</span><span class="identifier-syntax">work</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">rubric</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">link</span><span class="plain-syntax">)</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">link</span><span class="plain-syntax">, </span><span class="string-syntax">"href='inform:</span><span class="comment-syntax">Extensions/Documentation/");</span>
<span class="string-syntax">    Works::escape_apostrophes(link, work-&gt;author_name);</span>
<span class="string-syntax">    WRITE_TO(link, "</span><span class="plain-syntax">/</span><span class="string-syntax">");</span>
<span class="string-syntax">    Works::escape_apostrophes(link, work-&gt;title);</span>
<span class="string-syntax">    WRITE_TO(link, "</span><span class="plain-syntax">.</span><span class="identifier-syntax">html</span><span class="character-syntax">' ");</span>
<span class="character-syntax">    if (Str::len(rubric) &gt; 0) WRITE_TO(link, "title=\"%S\" ", rubric);</span>
<span class="character-syntax">    else WRITE_TO(link, "title=\"%X\" ", work);</span>
<span class="character-syntax">    WRITE_TO(link, "style=\"text-decoration: none\"");</span>
<span class="character-syntax">    HTML_OPEN_WITH("a", "%S", link);</span>
<span class="character-syntax">    DISCARD_TEXT(link)</span>
<span class="character-syntax">}</span>

<span class="character-syntax">void Works::escape_apostrophes(OUTPUT_STREAM, text_stream *S) {</span>
<span class="character-syntax">    LOOP_THROUGH_TEXT(pos, S) {</span>
<span class="character-syntax">        inchar32_t c = Str::get(pos);</span>
<span class="character-syntax">        if ((c == '</span><span class="plain-syntax">\</span><span class="character-syntax">''</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="character-syntax">'\"'</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="character-syntax">' '</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="character-syntax">'&amp;'</span><span class="plain-syntax">) ||</span>
<span class="plain-syntax">            (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="character-syntax">'&lt;'</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="character-syntax">'&gt;'</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="character-syntax">'%'</span><span class="plain-syntax">))</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"%%%x"</span><span class="plain-syntax">, (</span><span class="reserved-syntax">int</span><span class="plain-syntax">) </span><span class="identifier-syntax">c</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">else</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">PUT</span><span class="plain-syntax">(</span><span class="identifier-syntax">c</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">}</span>

<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Works::end_extension_link</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUTPUT_STREAM</span><span class="plain-syntax">, </span><span class="reserved-syntax">inbuild_work</span><span class="plain-syntax"> *</span><span class="identifier-syntax">work</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">HTML_CLOSE</span><span class="plain-syntax">(</span><span class="string-syntax">"a"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>The function Works::escape_apostrophes is used in Extensions Index Page (<a href="7-eip.html#SP1_2_2_4_4_1">&#167;1.2.2.4.4.1</a>), The Installer (<a href="7-ti.html#SP2_4_2_1">&#167;2.4.2.1</a>).</li></ul>
<nav role="progress"><div class="progresscontainer">
    <ul class="progressbar"><li class="progressprev"><a href="2-gnr.html">&#10094;</a></li><li class="progresschapter"><a href="P-wtmd.html">P</a></li><li class="progresschapter"><a href="1-sm.html">1</a></li><li class="progresscurrentchapter">2</li><li class="progresssection"><a href="2-gnr.html">gnr</a></li><li class="progresscurrent">wrk</li><li class="progresssection"><a href="2-edt.html">edt</a></li><li class="progresssection"><a href="2-cps.html">cps</a></li><li class="progresssection"><a href="2-ce.html">ce</a></li><li class="progresssection"><a href="2-rqr.html">rqr</a></li><li class="progresssection"><a href="2-nst.html">nst</a></li><li class="progresssection"><a href="2-rgs.html">rgs</a></li><li class="progresssection"><a href="2-jm.html">jm</a></li><li class="progresssection"><a href="2-lcn.html">lcn</a></li><li class="progresschapter"><a href="3-bg.html">3</a></li><li class="progresschapter"><a href="4-em.html">4</a></li><li class="progresschapter"><a href="5-es.html">5</a></li><li class="progresschapter"><a href="6-st.html">6</a></li><li class="progresschapter"><a href="7-tm.html">7</a></li><li class="progressnext"><a href="2-edt.html">&#10095;</a></li></ul></div>
</nav><!-- End of weave -->

		</main>
	</body>
</html>

